#include <iostream>

#include "include/Joueur.h"
#include "include/Pion.h"
#include "include/MissionStrategy.h"
#include "include/Territoire.h"
#include "include/Jeu.h"
#include "include/De.h"
#include "include/PionManager.h"


using namespace std;

Couleur::Couleur(enum CouleurEnum _couleur) 
   : couleur_enum(_couleur) 
{
   switch(_couleur)
   {
      case JAUNE:
         couleur_rgba[0] = 1.0; couleur_rgba[1] = 1.0; couleur_rgba[2] = 0.0; couleur_rgba[3] = 1.0;
         break;
      case ROUGE:
         couleur_rgba[0] = 1.0; couleur_rgba[1] = 0.0; couleur_rgba[2] = 0.0;  couleur_rgba[3] = 1.0;
         break;
      case BLEU:
         couleur_rgba[0] = 0.0; couleur_rgba[1] = 0.0; couleur_rgba[2] = 1.0; couleur_rgba[3] = 1.0; 
         break;
      case NOIR:
         couleur_rgba[0] = 0.0; couleur_rgba[1] = 0.0; couleur_rgba[2] = 0.0; couleur_rgba[3] = 1.0; 
         break;
      case VIOLET:
         couleur_rgba[0] = 0.5; couleur_rgba[1] = 0.0; couleur_rgba[2] = 0.5; couleur_rgba[3] = 1.0; 
         break;
      case VERT:
         couleur_rgba[0] = 0.0; couleur_rgba[1] = 1.0; couleur_rgba[2] = 0.0;  couleur_rgba[3] = 1.0;
         break;
   }
}

Couleur::Couleur(const float* _couleur_rgba)
{
   couleur_rgba[0] = _couleur_rgba[0];
   couleur_rgba[1] = _couleur_rgba[1];
   couleur_rgba[2] = _couleur_rgba[2];
   couleur_rgba[3] = _couleur_rgba[3];
}

Joueur::Joueur(const char * _nom, Couleur::CouleurEnum _couleur)
   : nom(new char[strlen(_nom)+1]), couleur(new Couleur(_couleur)), mission(NULL)
{
   strcpy(nom, _nom);
}

Joueur::~Joueur()
{
   //printf("Destruction du Joueur %s !\n", nom);
   delete []nom;
   delete mission;
   vector<Pion*>::const_iterator pions_ite;
   for(pions_ite = getPions()->begin();
       pions_ite != getPions()->end();
       pions_ite++)
      delete *pions_ite;
}

void Joueur::addPion(Territoire * _territoire, int nb)
{
   if ( nb >= PionManager::LEVEL3 )
      addPion(_territoire, nb, PionManager::LEVEL3);
   else
      if ( nb >= PionManager::LEVEL2 )
         addPion(_territoire, nb, PionManager::LEVEL2);
      else
         if ( nb >= PionManager::LEVEL1 )
            addPion(_territoire, nb, PionManager::LEVEL1);
}

void Joueur::addPion(Territoire * _territoire, int nb, PionManager::Level _level)
{
   int nbLevel = nb / _level;

   for (int i=0; i<nbLevel; i++)
   {
      pions.push_back( new Pion(this, _territoire, _level) ); 
      _territoire->addPion( pions.back() );
   }
   if ( nb % _level )
      addPion(_territoire, nb % _level);
}

void Joueur::removePion(Territoire * _territoire, int nb)
{
   if ( nb >= PionManager::LEVEL3 )
      removePion(_territoire, nb, PionManager::LEVEL3);
   else
      if ( nb >= PionManager::LEVEL2 )
         removePion(_territoire, nb, PionManager::LEVEL2);
      else
         if ( nb >= PionManager::LEVEL1 )
            removePion(_territoire, nb, PionManager::LEVEL1);
}

void Joueur::removePion(Territoire * _territoire, int nb, PionManager::Level _level)
{
   int nbLevel = nb / _level;
   for (int i=0; i<nbLevel; i++)
   {
      Pion* pion = _territoire->getPionByLevel( _level );
      if ( pion )
      {
         _territoire->removePion( pion );
         removePion( pion );
         delete pion;
      }
   }
   if ( nb % _level )
      removePion(_territoire, nb % _level);
}

void Joueur::removePion(Pion* _pion)
{
  vector<Pion*>::iterator pions_ite;
   for(pions_ite = getPions()->begin();
       pions_ite != getPions()->end();
       pions_ite++)
   {  
      if ( (*pions_ite) == _pion )
      {
         pions.erase( pions_ite );
         break;
      }
   }
}

bool Joueur::missionAccomplie()
{
   return mission->estAccomplie( this );
}

ostream & operator << (ostream & out, const Joueur & _joueur) 
{ 
   out << "Joueur" << endl;
   out << "nom: " << _joueur.getNom() << endl;

   vector<Pion*>::const_iterator pions_ite;
   for(pions_ite = _joueur.getPions()->begin();
       pions_ite != _joueur.getPions()->end();
       pions_ite++)
   {
      out << **pions_ite << endl;
   }

   return out;
}
